// 可辨识联合
interface Square {
    kind: "square";
    size: number;
}
interface Rectangle {
    kind: "rectangle";
    width: number;
    height: number;
}
interface Circle {
    kind: "circle";
    radius: number;
}

type Shape = Square | Rectangle | Circle;

function assertNever(x: never): never {
    throw new Error("Unexpected object: " + x);
}
function area(type: Shape) {
    switch (type.kind) {
        case 'square': return type.size * type.size;
        case 'rectangle': return type.width * type.height;
        case 'circle': return Math.PI * type.radius ** 2;
        default: return assertNever(type);
    }
}


// Pick
// pick对象的某些个属性 + 排除对象的某些个属性  => omit （忽略某些属性，挑出其他的）
interface Person {
    name: string;
    mis: string;
    age: number;
    avatar: string;
}
type User = Pick<Person, 'name' | 'age'> // 调出对象某几个属性  type User = { name: string; age: number; }
type User1 = Omit<Person, 'name' | 'age'> // 忽略对象某几个属性   type User1 = { mis: string; avatar: string; }
type User2 = Exclude<keyof Person, 'age'> // 获取剩下的联合属性  type User2 = "name" | "mis" | "avatar"
type User3 = Pick<Person, Exclude<keyof Person, 'age'>>  // type User1 = { mis: string; avatar: string; name: string; }

let p: User2 = 'avatar'
p = 'mis'
p = 'name'


// 场景：封装别人的组件的时候遇到同名的接口冲突了怎么办，怎么复用别人组件的接口
interface ButtonProps {
    className?: string;
    size?: 'small' | 'normal' | 'large';
    type?: 'normal' | 'primary' | 'success' | 'warning' | 'danger';
    shape?: 'text' | 'circle' | 'rect';
    hoverShape?: boolean;
    icon?: string;
    rightIcon?: string;
    ghost?: boolean;
    dashed?: boolean;
    loading?: boolean;
    disabled?: boolean;
    htmlType?: 'button' | 'submit' | 'reset';
    onClick?: any;
}
// onClick继承的时候不兼容，这时候我们需要剔除它，保留其他的
// el1:
interface PlugButtonProps extends Pick<ButtonProps, Exclude<keyof ButtonProps, 'onClick'>> {
    onClick?: (event: MouseEvent, button: any) => void;
}
// el2:
interface PlugButtonProps extends Omit<ButtonProps, 'onClick'> {
    onClick?: (event: MouseEvent, button: any) => void;
}

interface FilterState {
    taskNames?: Array<{
        pdCode: string;
        pdName: string;
    }>;
    submitStart?: string;
    submitEnd?: string;
    applicant?: {
        value: string;
        text: string;
    };
}
// 怎么让我传进来的 key和value能够对得上？？？
const handleOnChange = <T extends keyof FilterState>(key: T, value: FilterState[T]): void => {
    console.log(key, value);
}

handleOnChange('submitStart', 'zs')


interface UserType {
    name: string;
    age: number;
}

type optional = Partial<UserType>
// ---->>>
// type optional = {
//     name?: string | undefined;
//     age?: number | undefined;
// }

type option = Record<keyof UserType, any>
// ------>>>>
// type option = {
//     name: any;
//     age: any;
// }
